package com.naiterui.ehp.bs.patient.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import com.naiterui.common.repository.page.JpaPageConvertor;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.domain.ConsultBill;
import com.naiterui.ehp.bp.domain.Patient;
import com.naiterui.ehp.bp.domain.PatientAccount;
import com.naiterui.ehp.bp.domain.PatientAccountHistory;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bs.patient.dao.IConsultBillDao;
import com.naiterui.ehp.bs.patient.exception.ExceptionCodes;
import com.naiterui.ehp.bs.patient.repository.IApPatientAccountHistoryRepository;
import com.naiterui.ehp.bs.patient.repository.IApPatientAccountRepository;
import com.naiterui.ehp.bs.patient.service.IPatientAccountService;
import com.naiterui.ehp.bs.patient.service.IPatientService;
import com.naiterui.ehp.bs.patient.utils.constants.PatientConstant;
import com.naiterui.ehp.bs.patient.vo.account.AccountHistoryVO;
import com.naiterui.ehp.bs.patient.vo.account.PatientAccountDetailVO;
import com.naiterui.ehp.bs.patient.vo.account.PayInfoVO;
import com.naiterui.ehp.bs.patient.vo.account.PersonalCenterVO;

/**
 * 患者钱包账户业务接口实现
 *
 * @author Amber
 * @since 1.0.0
 */
@Service
public class ApPatientAccountServiceImpl implements IPatientAccountService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApPatientAccountServiceImpl.class);

    @Autowired
    private IApPatientAccountRepository patientAccountRepository;
    @Autowired
    private IApPatientAccountHistoryRepository patientAccountHistoryRepository;
    @Autowired
    private IPatientService patientService;
    @Autowired
    private IConsultBillDao consultBillDao;

    @Override
    public PersonalCenterVO getPersonalCenterInfo(Patient patient) throws BusinessException {
        PersonalCenterVO accountVO = new PersonalCenterVO();
        if (patient != null) {
            PatientAccount patientAccount = this.patientAccountRepository.findFirstByPatientId(patient.getId());
            int unPayNum = this.consultBillDao.getUpPayBill(patient.getId());
            accountVO.setBalance(patientAccount.getGeneralAccBal());
            accountVO.setNoPayNum(unPayNum);
            return accountVO;
        }
        return accountVO;
    }

    @Override
    public PatientAccountDetailVO getAccountDetail(Long patientId, int page, int num) throws BusinessException {
        PatientAccountDetailVO accountDetailVO = new PatientAccountDetailVO();
        Patient patient = this.patientService.getPatient(patientId);
        // 用户信息校验
        if (patient == null) {
            LOGGER.error("-----------patient account detail error ；patient not exist patientId {}", patientId);
            throw new BusinessException(ExceptionCodes.PATIENT_NOT_EXIST);
        }

        if (patient.getAccountStatus() != 0) {
            LOGGER.error("-----------patient account detail error; patient account status wrong。 patientId {}", patientId);
            throw new BusinessException(ExceptionCodes.PATIENT_ACCOUNT_ERROR);
        }
        // 钱包余额
        PatientAccount patientAccount = this.patientAccountRepository.findFirstByPatientId(patientId);
        accountDetailVO.setBalance(patientAccount.getGeneralAccBal());

        // 账户明细分页信息VO
        PageVO<AccountHistoryVO> accountHistoryPageVO = new PageVO<>();
        // 账户明细VO结果集
        List<AccountHistoryVO> accountHistoryVOList = new ArrayList<>();

        // 分页获取患者账户流水
        PageVO<PatientAccountHistory> accountHistoryPage =
                JpaPageConvertor.pageConvert(this.patientAccountHistoryRepository.findByPatientId(patientId,
                                                                                                  PageRequest.of(page, num)));

        // 支付账单id
        List<Long> billIds = new ArrayList<>();
        for (PatientAccountHistory accountHistory : accountHistoryPage.getResult()) {

            AccountHistoryVO accountHistoryVO = new AccountHistoryVO();
            accountHistoryVO.setAmount(accountHistory.getChangeAmount());// 如果收入则金额不变，支出需要判断是否混合支付

            accountHistoryVO.setDate(accountHistory.getCreatedAt().getTime() / 1000);// TODO:1000数字不能写在这
            accountHistoryVO.setType(accountHistory.getChangeType());
            String desc = "";
            // 如果类型为支出
            if (accountHistory.getChangeType() == PatientAccountHistory.CHANGE_TYPE_PAYOUT && accountHistory.getChangeOrigin() != null) {
                billIds.add(accountHistory.getChangeOrigin());
                accountHistoryVO.setChangeOrigin(accountHistory.getChangeOrigin());
                desc = "支付医生的咨询诊金";
            } else if (accountHistory.getIncomeCause() == PatientAccountHistory.INCOME_CAUSE_PAY) {// 收入，且收入原因为支付返现
                desc = String.format(PatientConstant.INCOME_PT_DESC_MAP.get(accountHistory.getIncomeCause()), "某医生");
            } else { // 其他收入类型
                desc = PatientConstant.INCOME_PT_DESC_MAP.get(accountHistory.getIncomeCause());
            }

            // 设置描述
            accountHistoryVO.setDesc(desc);
            accountHistoryVOList.add(accountHistoryVO);
        }

        if (billIds.size() > 0) {
            // 获取支出流水相关账单信息
            Map<Long, ConsultBill> billMap = this.consultBillDao.getBillsByIds(billIds);
            for (AccountHistoryVO vo : accountHistoryVOList) {
                if (vo.getChangeOrigin() != null) {
                    ConsultBill bill = billMap.get(vo.getChangeOrigin());
                    PayInfoVO payInfoVO = new PayInfoVO();
                    payInfoVO.setStatus("已支付");
                    payInfoVO.setBalancePay(bill.getBalancePay());
                    payInfoVO.setPayType(bill.getPayType());
                    payInfoVO.setThirdPay(bill.getThirdPay());
                    payInfoVO.setThirdType(bill.getThirdType());
                    vo.setPayInfo(payInfoVO);
                }
            }
        }

        //accountHistoryPageVO = CustomizedPageConvertor.pageConvert(accountHistoryPage, accountHistoryVOList);
        accountHistoryPageVO = PageVO.newBuilder()
                                     .pageNo(accountHistoryPage.getPageNo())
                                     .pageSize(accountHistoryPage.getPageSize())
                                     .totalCount((int) accountHistoryPage.getTotalCount())
                                     .result(accountHistoryVOList)
                                     .offset(accountHistoryPage.getOffset())
                                     .build();
        // 设置账户明细分页表
        accountDetailVO.setHistorys(accountHistoryPageVO);
        return accountDetailVO;
    }
}
